/**
 * 
 */
package vn.smartware.co.framework.plugin;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Properties;

import javax.servlet.ServletContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import vn.smartware.co.framework.common.BaseConstant;
import vn.smartware.co.framework.config.ActionMapping;
import vn.smartware.co.framework.config.PropertyResources;
import vn.smartware.co.framework.config.SystemConfig;
import vn.smartware.co.framework.exception.ClientException;
import vn.smartware.co.framework.exception.FatalException;
import vn.smartware.co.framework.exception.ServerException;


/**
 * FileResource
 */

public class FileResource implements Serializable {
	
	/**
	 * serialVersionUID
	 */
	private static final long serialVersionUID = 8241253063598588953L;

	private static Log log = LogFactory.getLog(FileResource.class);

	/**
	 * unique instance of FileResource 
	 */
	static FileResource fileResource;

	private SystemConfig mapping;
//	private ValidatorResources validatorResource;
	private SystemResources systemResources = null;
	
	/**
	 * <p>Server Side Environment Flag</p> 
	 */
	private boolean serverEnv = false;
	
	/**
	 * <p>Client Side Environment Flag</p>
	 */
	private boolean clientEnv = false;

	/**
	 * <p>ApplicationResource.properties</p>
	 */
	private Properties messageResource;
		
	/**
	 * @param messageResource messageResource
	 */
	public void setMessageResource(Properties messageResource) {
		this.messageResource = messageResource;
	}
		
	/**
	 * Client Constractor.
	 *
	 * @throws IOException
	 * @throws ClientException 
	 * @throws FatalException 
	 */
//	public FileResource() throws IOException, ClientException, SAXException,
//			FatalException {
	public FileResource() throws IOException, ClientException, FatalException {
		
		clientEnv = true;
		serverEnv = false;
		systemResources = SystemResources.getInstance();
		
		setMessageResource();
		
//		setValidatorResource();
		
		setConfigResource();
	}
	
	/**
	 * Server Constractor.
	 * 
	 * @param context
	 * @throws ServerException 
	 * @throws FatalException 
	 */
	public FileResource(ServletContext context) throws ServerException,
			FatalException {
		
		serverEnv = true;
		clientEnv = false;
		systemResources = SystemResources.getInstance(context);
		
//		setMessageResource(context);
		
//		setValidatorResource(context);
		
		setConfigResource(context);
	}

	/**
	 * @return messageResource
	 * 
	 */
	public Properties getMessageResource() {
		return messageResource;
	}

	
	/**
	 * Client Resources.
	 * @throws IOException 
	 * @throws ClientException 
	 */
	synchronized public void setMessageResource() throws IOException,
			ClientException {
		
		Properties prop = null;

		ClassLoader loader = this.getClass().getClassLoader();
		
		InputStream is = loader.getResourceAsStream(systemResources.getClientResourceFile());

		if (is == null) {
			throw new ClientException(systemResources.getClientResourceFile() + " is NotFound.");
		}
		
		prop = PropertyResources.getProperties(systemResources.getClientResourceFile(), is);
				
		setMessageResource(prop);
	}
	
	/**
	 * Server Resources.
	 * 
	 * @param context
	 * @throws IOException 
	 * @throws ServerException 
	 */
//	synchronized public void setMessageResource(ServletContext context)
//			throws IOException, ServerException {
//		
//		Properties prop = null;
//		
//		String serverResource = BaseConstant.MESSAGE_SERVER_DIR + systemResources.getServerResourceFile();
//		
//		InputStream is = context.getResourceAsStream(serverResource);
//
//		if (is == null) {
//			throw new ServerException(serverResource + " is NotFound.");
//		}
//		
//		prop = PropertyResources.getProperties(serverResource, is);
//		
//		setMessageResource(prop);
//	}

	/**
	 * Client Resources.
	 * @throws IOException 
	 * @throws ClientException 
	 * @throws SAXException 
	 */
//	synchronized public void setValidatorResource() throws IOException,
//			ClientException, SAXException {
//		
//		ClassLoader loader = this.getClass().getClassLoader();
//		
//		InputStream is = loader.getResourceAsStream(systemResources.getValidatorFile());
//		
//		if (is == null) {
//			throw new ClientException(systemResources.getValidatorFile() + " is NotFound.");
//		}
//		
//		this.validatorResource = new ValidatorResources(is);
//	}
	
	/**
	 * Server Resources.
	 * @param context
	 * @throws IOException 
	 * @throws ServerException 
	 * @throws SAXException 
	 */
//	synchronized public void setValidatorResource(ServletContext context)
//			throws IOException, ServerException, SAXException {
//		
//		String validatorFile = BaseConstant.VALIDATOR_SERVER_DIR + systemResources.getValidatorFile();
//		
//		InputStream is = context.getResourceAsStream(validatorFile);
//		
//		if (is == null) {
//			throw new ServerException(validatorFile + " is NotFound.");
//		}
//		
//		this.validatorResource = new ValidatorResources(is);
//	}
	
	/**
	 * Client Resources.
	 * 
	 * @throws ClientException
	 * @throws FatalException 
	 */
	synchronized public void setConfigResource() throws ClientException,
			FatalException {
		
		ClassLoader loader = this.getClass().getClassLoader();
		
		InputStream is = loader.getResourceAsStream(systemResources.getConfigFile());
		
		if (is == null) {
			throw new ClientException(systemResources.getConfigFile() + " is Not Found.");
		}
		
		mapping = ActionMapping.loadMapping(is);
	}
	
	/**
	 * Server Resources.
	 * 
	 * @param context
	 * @throws ServerException
	 * @throws FatalException 
	 */
	synchronized public void setConfigResource(ServletContext context)
			throws ServerException, FatalException {
		
		String configFile = BaseConstant.CONFIG_SERVER_DIR + systemResources.getConfigFile();
		
		InputStream is = context.getResourceAsStream(configFile);
		
		if (is == null) {
			throw new ServerException(configFile + " is NotFound.");
		}
		
		mapping = ActionMapping.loadMapping(is);
	}
	
	/**
	 * @return clientEnv
	 * 
	 */
	public boolean isClientEnv() {
		return clientEnv;
	}

	/**
	 * @param clientEnv clientEnv
	 * 
	 */
	public void setClientEnv(boolean clientEnv) {
		this.clientEnv = clientEnv;
	}

	/**
	 * @return serverEnv
	 * 
	 */
	public boolean isServerEnv() {
		return serverEnv;
	}

	/**
	 * @param serverEnv serverEnv
	 * 
	 */
	public void setServerEnv(boolean serverEnv) {
		this.serverEnv = serverEnv;
	}

	/**
	 * @return FileResource
	 * @throws ClientException
	 */
	public static FileResource getInstance() throws ClientException {
		
		try {
			if (fileResource == null){
				fileResource = new FileResource();
			}
			return fileResource;
		} catch (IOException e) {
			log.error("FileResource get Error.", e);
			throw new ClientException("FileResource get Error.", e);
		} 
//		/*catch (SAXException e) {
//			log.error("FileResource get Error.", e);
//			throw new ClientException("FileResource get Error.", e);
//		} */
		catch (FatalException e) {
			log.error("FileResource get Error.", e);
			throw new ClientException("FileResource get Error.", e);
		}
	}
	
	/**
	 * getInstance
	 * @param context
	 * @return FileResource
	 * @throws ServerException
	 */
	public static FileResource getInstance(ServletContext context)
			throws ServerException {
		
		try {
			if (fileResource == null){
				fileResource = new FileResource(context);
			}
			return fileResource;
		} catch (FatalException e) {
			log.error("FileResource get Error.", e);
			throw new ServerException("FileResource get Error.", e);
		}
	}

	/**
	 * @return SmsConfig
	 */
	public SystemConfig getConfig(){
		return this.mapping;
	}
	
	/**
	 * get validator
	 * @return ValidatorResources
	 */
//	public ValidatorResources getValidator(){
//		return this.validatorResource;
//	}
}
